/*
 * UCache Metadata Database API
 * Copyright (C) 2013 Will Dignazio
 */

#include <mstore.h>
#include "internal.h"

/*
 * The idea behind that ucache database, and the 
 * accompanying ucache database api, is that one could
 * use any database, key-value store, or distributed system
 * to power the fast lookup or cacheing of ucache.
 * 
 * The basic goal of the ucache database is this: 
 * 	open -> ucache -> umdb ________________-> cached file
 *				    \_ get        /
 *					   \_ put/
 *
 * Where 'get' is checking if the file key (path/filename) has been 
 * put into ucache yet. If it has, return the UCacheObj and go from there.
 * If it hasn't we have ot "copy-on read" the file into the designated
 * cache mount, then put the key into the cache db.
 */

int
umdb_open(UCache* uc, Error *err)
{
	MStore* mstore;
	if(uc->mstore != NULL) {
		error(err, "UCache instance of MStore is not open.");
		return UMDB_EOPEN;
	}

	mstore = mstore_init(uc->args->nodesz, err);
	if(mstore == NULL)
		return UMDB_ERR;

	uc->mstore = mstore;
	return 0;
}

int
umdb_close(UCache* uc, Error *err)
{
	return UMDB_ENOIMP;
}

int
umdb_put(UCacheObj* uobj, UCache* uc, Error *err)
{
	int r;

	if(uc->mstore == NULL) {
		error(err, "Invalid ucache == NULL");
		return UMDB_ECLOSED;
	}

	r = mstore_insert(uc->mstore, uobj->bufsz, uobj->co_ref.vbuf, err);
	if(r != 0)
		return UMDB_ERR;

	return 0;
}

int
umdb_get(MHash mid, UCacheObj** uobj, UCache* uc, Error *err)
{
	int r;
	r = mstore_search((void**)uobj, mid, uc->mstore, err);
	return r;
}

int
umdb_delete(UCacheObj* uobj, UCache* uc, Error *err)
{
	MHash mid;
	int r;

	mid = mhash(uobj->co_ref.vbuf, uobj->bufsz);
	r = mstore_delete(&mid, uc->mstore, err);

	return r;
}
